﻿
namespace TransportAnalizer.DataTests
{
    using System;
    using System.Linq;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using TransportAnalizer_2._0.Model;
    [TestClass]
    public class NodeTypeBusinessContextTests:FunctionalTest
    {
        #region NodeTypeTests

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void AddNewNodeType_ThrowsException_WhenNameIsNull()
        {
            using (var bc = new NodeTypeBusinessContext())
            {
                var nodeType = new NodeType
                {
                    Name = null,
                    Passage = 30,
                    Regulation = RegulationType.NoRegulation,
                    Description="description"
                };

                bc.CreateNodeType(nodeType);
            }
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void AddNewNodeType_ThrowsException_WhenDescriptionIsNull()
        {
            using (var bc = new NodeTypeBusinessContext())
            {
                var nodeType = new NodeType
                {
                    Name = null,
                    Passage = 30,
                    Regulation = RegulationType.NoRegulation
                };

                bc.CreateNodeType(nodeType);
            }
        }
        
        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void AddNewNodeType_ThrowsException_WhenNameIsEmpty()
        {
            using (var bc = new NodeTypeBusinessContext())
            {
                var nodeType = new NodeType
                {
                    Name = "",
                    Passage = 30,
                    Regulation = RegulationType.NoRegulation,
                    Description="description"
                };

                bc.CreateNodeType(nodeType);
            }
        }

        // TODO: Подумать над тестами для Double Passage и RegulationType

        [TestMethod]
        public void AddNewNodeType_NodeTypeIsStoredInDataStore()
        {
            using (var bc = new NodeTypeBusinessContext())
            {
                var nodeType = new NodeType
                {
                    Name = "Новый тип",
                    Passage = 30,
                    Regulation = RegulationType.NoRegulation,
                    Description = "description"
                };

                bc.CreateNodeType(nodeType);

                bool exists = bc.DataContext.NodeTypeSet.Any(c => c.Id == nodeType.Id);

                Assert.IsTrue(exists);
            }
        }

        [TestMethod]
        public void UpdateNodeType_AppliedValuesAreStoredInDataStore()
        {
            using (var bc = new NodeTypeBusinessContext())
            {
                // Arrange
                var nodeType = new NodeType
                {
                    Name = "Новый тип",
                    Passage = 30,
                    Regulation = RegulationType.NoRegulation,
                    Description=""
                };

                bc.CreateNodeType(nodeType);

                const string newName = "Новый тип 2",
                             newDescription = "Новое описание";
                const double newPassage = 40;
                const RegulationType newRegulationType=RegulationType.GiveWay;

                nodeType.Name = newName;
                nodeType.Description = newDescription;
                nodeType.Passage = newPassage;
                nodeType.Regulation = newRegulationType;

                // Act
                bc.UpdateNodeType(nodeType);

                // Assert
                bc.DataContext.Entry(nodeType).Reload();

                Assert.AreEqual(newName, nodeType.Name);
                Assert.AreEqual(newPassage, nodeType.Passage);
                Assert.AreEqual(newRegulationType, nodeType.Regulation);
                Assert.AreEqual(newDescription, nodeType.Description);
            }
        }

        [TestMethod]
        public void GetNodeTypeList_ReturnsExpectedListOfNodeTypeEntities()
        {
            using (var bc = new NodeTypeBusinessContext())
            {
                bc.CreateNodeType(new NodeType { Name = "1", Regulation=RegulationType.Stop, Passage=30, Description="описание"});
                bc.CreateNodeType(new NodeType { Name = "2",Description="" });
                bc.CreateNodeType(new NodeType { Name = "3", Regulation = RegulationType.NoRegulation, Passage = 40,Description="" });

                var customers = bc.GetNodeTypeList();

                Assert.IsTrue(customers.ElementAt(0).Id == 1);
                Assert.IsTrue(customers.ElementAt(1).Id == 2);
                Assert.IsTrue(customers.ElementAt(2).Id == 3);

                // Use CollectionAssert by overriding Equals in entities
                // or using IComparer in CollectionAssert for a more full-proof
                // solution
            }
        }

        [TestMethod]
        public void DeleteCustomer_RemovesCustomerFromDataStore()
        {
            using (var bc = new NodeTypeBusinessContext())
            {
                var nodeType = new NodeType { Name = "1", Regulation = RegulationType.Stop, Passage = 30, Description = "описание" };
                bc.CreateNodeType(nodeType);
                bc.DeleteNodeType(nodeType);
                Assert.IsFalse(bc.DataContext.NodeTypeSet.Any());
            }
        }

        #endregion NodeTypeTests



    }
}
